package com.jtcoding.chat.service.impl;

import com.jtcoding.chat.common.enums.ResultCode;
import com.jtcoding.chat.config.FastDFSProperties;
import com.jtcoding.chat.dao.fastdfs.ResourceDao;
import com.jtcoding.chat.exception.ApiException;
import com.jtcoding.chat.model.FastDFSResource;
import com.jtcoding.chat.model.ResourceFromService;
import com.jtcoding.chat.model.ResourceLog;
import com.jtcoding.chat.service.ResourceService;
import lombok.extern.slf4j.Slf4j;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author jason.tang
 * @create 2019-01-25 15:23
 * @description 文件服务业务层实现类
 */
@Slf4j
@Service(value = "fileService")
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceDao resourceDao;

    @Autowired
    private FastDFSProperties fastDFSProperties;

    @PostConstruct
    private void autoStartup() {
        try {
            ClientGlobal.initByProperties(fastDFSProperties.generateProperties());
        } catch (Exception e) {
            log.error("FastDFS Client Init Fail!", e);
        }
    }

    /**
    * @Author jason.tang
    * @Description: 上传资源
    * @Date: 17:21 2019/1/25
    * @Param [resource]
    * @return com.jtcoding.chat.model.ResourceLog
    */
    @Transactional
    @Override
    public ResourceLog uploadResource(FastDFSResource resource) throws IOException, MyException {
        String fromService = resource.getFromService();
        String exc = resource.getName().substring(resource.getName().lastIndexOf(".") + 1);
        ResourceFromService rfs = resourceDao.getResourceFromService(fromService);
        if (rfs == null) {
            throw new ApiException(ResultCode.SERVICE_NOT_EXISTS);
        }
        if (rfs.getVaild() != 1) {
            throw new ApiException(ResultCode.SERVICE_EXPIRED);
        }
        // 文件属性信息
        NameValuePair[] valuePair = new NameValuePair[1];
        valuePair[0] = new NameValuePair("fromService", fromService);

        String[] uploadResults = null;
        try {
            uploadResults = storageClient.upload_file(resource.getContent(), exc, valuePair);
        } catch (Exception e) {
            throw new ApiException(ResultCode.UPDATE_FAILURE);
        }

        //上传文件成功会返回 groupName、rempteFileName
        String groupName = uploadResults[0];
        String remoteFileName = uploadResults[1];
        String fileUrl = "http:/" + getIP() + "/" + groupName + "/" + remoteFileName;
        ResourceLog resourceLog = ResourceLog.builder().originalName(resource.getName())
                .uploadFileName(remoteFileName.substring(remoteFileName.lastIndexOf("/") + 1))
                .resSize(getFileSizeUnitsOfKB(resource.getContent().length)).fromService(fromService).resType(resource.getResType())
                .resURL(fileUrl).status(1).groupName(groupName).remoteFileName(remoteFileName)
                .createDatetime(LocalDateTime.now()).refNum(resource.getRefNum()).build();

        List<ResourceLog> resourceLogs = resourceDao.getResourceLogByRefNum(resource.getResType(), resource.getRefNum());
        if (resourceLogs.size() > 0) {
            resourceLogs.forEach(r -> {
                r.setStatus(0);
                resourceDao.updateResourceLog(r);
            });
        }
        int rtn = resourceDao.addResourceLog(resourceLog);
        if (rtn == 0) {
            deleteResource(groupName, remoteFileName);
            throw new ApiException(ResultCode.UPDATE_FAILURE);
        }
        return resourceLog;
    }

    @Override
    public Boolean deleteResource(String groupName, String remoteFileName) throws IOException, MyException {
        int rtn = storageClient.delete_file(groupName, remoteFileName);
        if (rtn == 0) {
            return false;
        }
        return resourceDao.deleteResource(groupName, remoteFileName) > 0;
    }

    @Override
    public List<ResourceLog> getHistoryResource(Integer refNum, String resType) {
        return resourceDao.getHistoryResource(refNum, resType);
    }

    private double getFileSizeUnitsOfKB(long fileLength) {
        double size = (double) fileLength;
        return new BigDecimal(size / 1024).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
    }

    @Autowired
    @Lazy
    private StorageClient storageClient;
    @Autowired
    @Lazy
    private TrackerServer trackerServer;

    private String getIP() throws IOException {
        return trackerServer.getSocket().getInetAddress().toString();
    }


}